#include "Dictionary.h"

/*--------------------------------------------------------------------------------------
 *       Class:  Dictionary
 *      Method:  Dictionary
 * Description:  Constrói um dicionário
 *--------------------------------------------------------------------------------------
 */
Dictionary::Dictionary()
{
    // Inicializa os contadores
    memset(howmany, 0, sizeof(uint) * (_WD_SIZE + 1));
    count = 0;
}

/*--------------------------------------------------------------------------------------
 *       Class:  Dictionary
 *      Method:  add
 * Description:  Adiciona uma palavra
 *--------------------------------------------------------------------------------------
 */
void Dictionary::add(const string &word)
{
    uint len = word.length();

    // Quantidade de subpalavras
    uint split = ceil(len / (double) _WD_SIZE);
    // Tamanho médio para cada palavra
    uint div = ceil(len / (double) split);

    // Adiciona as primeiras subpalavras
    uint init = 0;
    for(uint i = 0; i < split - 1; i++)
    {
        put(word.substr(init, div));
        init += div;
    }

    // A última palavra fica com os caracteres restantes
    put(word.substr(init));
}

/*--------------------------------------------------------------------------------------
 *       Class:  Dictionary
 *      Method:  add
 * Description:  Adiciona uma palavra
 *--------------------------------------------------------------------------------------
 */
void Dictionary::put(string word)
{
    // Não insere palavras menores que 1
    if(word.length() <= 1)
        return;

    // Só adicona se não a palavra não foi encontrada
    if(words.find(word) == words.end())
    {
        words[word] = false;
        howmany[word.length()]++;
        count++;
    }
}

/*--------------------------------------------------------------------------------------
 *       Class:  Dictionary
 *      Method:  fill
 * Description:  Preenche todas as palavras em um vetor
 *--------------------------------------------------------------------------------------
 */
void Dictionary::fill(host_vector<WordPair> &vector)
{
    for(auto word : words)
    {
        WordPair wordPair;
        wordPair.hasFound = word.second ? 1 : 0 ;
        strcpy(wordPair.word, word.first.c_str());
        vector.push_back(wordPair);
    }
}

/*--------------------------------------------------------------------------------------
 *       Class:  Dictionary
 *      Method:  operator <<
 * Description:  Imprime as palavras encontradas
 *--------------------------------------------------------------------------------------
 */
ostream& operator <<(ostream &os, const Dictionary &words)
{
    for(auto word : words.words)
        os << word.first << endl;

    os << words.count << " words" << endl;
    for(uint i = 0; i < _WD_SIZE + 1; i++)
        os << i << ": " << words.howmany[i] << endl;

    return os;
}
